package com.wsecar.sharelogin.qq.core;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.widget.Toast;

import com.tencent.connect.UserInfo;
import com.tencent.connect.common.Constants;
import com.tencent.open.im.IM;
import com.tencent.open.miniapp.MiniApp;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import com.wsecar.sharelogin.R;
import com.wsecar.sharelogin.qq.bean.QQLoginInfo;
import com.wsecar.sharelogin.qq.bean.QQShareParamInfo;
import com.wsecar.sharelogin.qq.bean.QQUserInfo;
import com.wsecar.sharelogin.qq.bean.ShareInitConfig;
import com.wsecar.sharelogin.qq.listener.QQImCallBackListener;
import com.wsecar.sharelogin.qq.listener.QQLoginCallBackListener;
import com.wsecar.sharelogin.qq.listener.QQMiniAppCallBackListener;
import com.wsecar.sharelogin.qq.listener.QQShareResultListener;
import com.wsecar.sharelogin.qq.listener.QQUserInfoCallBackListener;

import org.json.JSONObject;

public class QQLoginImpl {
    private static final String SHARE_PREF_NAME = "openSdk.pref";
    private static final String KEY_TARGET_QQ_UIN = "target.uin";
    private boolean isServerSideLogin = false;
    private boolean isGetUserInfo = false;
    private UserInfo mInfo;
    private Activity mActivity;
    private ShareInitConfig shareInitConfig;
    private Tencent mTencent;
    private QQLoginInfo qqLoginInfo;
    private QQLoginCallBackListener loginCallBackListener;
    private QQUserInfoCallBackListener userInfoCallBackListener;
    private IUiListener userUiListener = new IUiListener() {
        @Override
        public void onComplete(Object response) {
            QQUserInfo qqUserInfo = null;
            if (null != response) {
                try {
                    JSONObject json = (JSONObject) response;
                    qqUserInfo = new QQUserInfo();
                    qqUserInfo.setRet(json.optInt("ret"));
                    qqUserInfo.setMsg(json.optString("msg"));
                    qqUserInfo.setNickname(json.optString("nickname"));
                    qqUserInfo.setIs_lost(json.optInt("is_lost"));
                    qqUserInfo.setGender(json.optString("gender"));
                    qqUserInfo.setGender_type(json.optInt("gender_type"));
                    qqUserInfo.setProvince(json.optString("province"));
                    qqUserInfo.setCity(json.optString("city"));
                    qqUserInfo.setYear(json.optString("year"));
                    qqUserInfo.setConstellation(json.optString("constellation"));
                    qqUserInfo.setFigureurl(json.optString("figureurl"));
                    qqUserInfo.setFigureurl_1(json.optString("figureurl_1"));
                    qqUserInfo.setFigureurl_2(json.optString("figureurl_2"));
                    qqUserInfo.setFigureurl_qq(json.optString("figureurl_qq"));
                    qqUserInfo.setFigureurl_qq_1(json.optString("figureurl_qq_1"));
                    qqUserInfo.setFigureurl_qq_2(json.optString("figureurl_qq_2"));
                    qqUserInfo.setFigureurl_type(json.optString("figureurl_type"));
                    qqUserInfo.setIs_yellow_vip(json.optString("is_yellow_vip"));
                    qqUserInfo.setVip(json.optString("vip"));
                    qqUserInfo.setYellow_vip_level(json.optString("yellow_vip_level"));
                    qqUserInfo.setLevel(json.optString("level"));
                    qqUserInfo.setIs_yellow_year_vip(json.optString("is_yellow_year_vip"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (null != userInfoCallBackListener) {
                userInfoCallBackListener.userInfo(qqUserInfo);
            }
        }

        @Override
        public void onError(UiError uiError) {
            if (null == uiError) {
                return;
            }
            if (null != userInfoCallBackListener) {
                userInfoCallBackListener.error(uiError.errorCode, uiError.errorMessage);
            }
        }

        @Override
        public void onCancel() {
            if (null != userInfoCallBackListener) {
                userInfoCallBackListener.cancle();
            }
        }
    };
    private IUiListener loginAuLoginListener = new IUiListener() {
        @Override
        public void onComplete(Object o) {
            if (null != o) {
                JSONObject values = (JSONObject) o;
                initOpenidAndToken(values);
            }
            if (isGetUserInfo) {
                getUserInfo();
            }
            if (null != loginCallBackListener) {
                loginCallBackListener.loginResult(qqLoginInfo);
            }
        }

        @Override
        public void onError(UiError uiError) {
            if (null == uiError) {
                return;
            }
            if (null != loginCallBackListener) {
                loginCallBackListener.error(uiError.errorCode, uiError.errorMessage);
            }
        }

        @Override
        public void onCancel() {
            if (null != loginCallBackListener) {
                loginCallBackListener.cancle();
            }
        }
    };

    public void login(Activity activity, ShareInitConfig shareInitConfig, boolean userInfoFlag, QQLoginCallBackListener loginCallBackListener, QQUserInfoCallBackListener userInfoCallBackListener) {
        this.mActivity = activity;
        this.isGetUserInfo = userInfoFlag;
        this.loginCallBackListener = loginCallBackListener;
        this.userInfoCallBackListener = userInfoCallBackListener;
        this.shareInitConfig = shareInitConfig;
        if (null == mTencent) {
            mTencent = Tencent.createInstance(shareInitConfig.getQqAppId(), activity);
        }
        if (!mTencent.isSessionValid()) {
            mTencent.login(activity, "all", loginAuLoginListener, true);
            isServerSideLogin = false;
        } else {
            if (isServerSideLogin) { // Server-Side 模式的登陆, 先退出，再进行SSO登陆
                mTencent.logout(activity);
                mTencent.login(activity, "all", loginAuLoginListener);
                isServerSideLogin = false;
                return;
            }
            mTencent.logout(activity);
            if (userInfoFlag) {
                getUserInfo();
            }

        }
    }

    private void initOpenidAndToken(JSONObject jsonObject) {
        try {
            String openId = jsonObject.getString(Constants.PARAM_OPEN_ID);
            String access_token = jsonObject.getString(Constants.PARAM_ACCESS_TOKEN);
            String pay_token = jsonObject.optString("pay_token");
            String expires_in = jsonObject.getString(Constants.PARAM_EXPIRES_IN);
            String pf = jsonObject.optString(Constants.PARAM_PLATFORM_ID);
            String pfkey = jsonObject.optString("pfkey");
            String msg = jsonObject.optString("msg");
            String login_cost = jsonObject.optString("login_cost");
            String query_authority_cost = jsonObject.optString("query_authority_cost");
            String authority_cost = jsonObject.optString("authority_cost");
            String expires_time = jsonObject.optString("expires_time");
            qqLoginInfo = new QQLoginInfo();
            qqLoginInfo.setOpenid(openId);
            qqLoginInfo.setAccess_token(access_token);
            qqLoginInfo.setPay_token(pay_token);
            qqLoginInfo.setExpires_in(expires_in);
            qqLoginInfo.setPf(pf);
            qqLoginInfo.setPfkey(pfkey);
            qqLoginInfo.setMsg(msg);
            qqLoginInfo.setLogin_cost(login_cost);
            qqLoginInfo.setQuery_authority_cost(query_authority_cost);
            qqLoginInfo.setAuthority_cost(authority_cost);
            qqLoginInfo.setExpires_time(expires_time);
            if (!TextUtils.isEmpty(access_token) && !TextUtils.isEmpty(expires_in)
                    && !TextUtils.isEmpty(openId)) {
                mTencent.setAccessToken(access_token, expires_in);
                mTencent.setOpenId(openId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取用户数据
     */
    public void getUserInfo() {
        if (mTencent != null && mTencent.isSessionValid()) {
            mInfo = new UserInfo(mActivity, mTencent.getQQToken());
            mInfo.getUserInfo(userUiListener);
        } else {
            if (null != userInfoCallBackListener) {
                userInfoCallBackListener.userInfo(null); // 获取用户数据失败
            }
        }
    }


    /**
     * 拉起小程序
     */
    public void launchMiniApp(Activity activity, ShareInitConfig shareInitConfig, QQMiniAppCallBackListener listener) {
        this.mActivity = activity;
        this.shareInitConfig = shareInitConfig;

        if (TextUtils.isEmpty(shareInitConfig.getTargetMiniAppId())) {
            return;
        }
        int ret = MiniApp.MINIAPP_UNKNOWN_TYPE;
        if (null == mTencent) {
            mTencent = Tencent.createInstance(shareInitConfig.getQqAppId(), activity);
        }
        ret = mTencent.startMiniApp(mActivity, shareInitConfig.getTargetMiniAppId(), shareInitConfig.getTargetMiniAppPath(), shareInitConfig.getTargetMiniAppVersion());
        if (ret != MiniApp.MINIAPP_SUCCESS) {
            String errorStr = "";
            if (ret == MiniApp.MINIAPP_ID_EMPTY) {
                errorStr = activity.getString(R.string.qqconnect_mini_app_id_empty);
            } else if (ret == MiniApp.MINIAPP_ID_NOT_DIGIT) {
                errorStr = activity.getString(R.string.qqconnect_mini_app_id_not_digit);
            }
            if (null != listener) {
                listener.error(ret, errorStr);
            }
        } else {
            listener.error(ret, "");
        }
    }


    /**
     * QQ 聊天
     */
    public void chartImWithQQ(Activity activity, String otherQQ, int imtype, ShareInitConfig shareInitConfig, QQImCallBackListener listener) {
        if (null == mTencent) {
            mTencent = Tencent.createInstance(shareInitConfig.getQqAppId(), activity);
        }
        if (mTencent.isSessionValid()) {
            if (!TextUtils.isEmpty(otherQQ)) {
                saveTargetUin(otherQQ);
                jumpIMWithType(imtype, listener);
            } else {
                if (null != listener) {
                    listener.error(-1, "QQ号不能为空");
                }
            }

        } else {
            if (null != listener) {
                listener.error(-1, "请先登录");
            }
        }
    }


    /**
     * 根据传参拉起不同的IM业务
     *
     * @param type
     */
    private void jumpIMWithType(int type, QQImCallBackListener listener) {
        int ret = IM.IM_UNKNOWN_TYPE;
        if (type == Constants.IM_AIO) {
            ret = mTencent.startIMAio(mActivity, getTargetUin(), mActivity.getPackageName());
        } else if (type == Constants.IM_AUDIO_CHAT) {
            ret = mTencent.startIMAudio(mActivity, getTargetUin(), mActivity.getPackageName());
        } else if (type == Constants.IM_VIDEO_CHAT) {
            ret = mTencent.startIMVideo(mActivity, getTargetUin(), mActivity.getPackageName());
        }
        String msg = "";
        if (ret != IM.IM_SUCCESS) {
            msg = "start IM conversation failed. error:";
        }
        if (null != listener) {
            listener.error(ret, msg);
        }
    }


    private String getTargetUin() {
        SharedPreferences share = mActivity.getSharedPreferences(SHARE_PREF_NAME, 0);
        return share.getString(KEY_TARGET_QQ_UIN, null);
    }

    /**
     * 设置成持久化，后续可以不用每次弹出
     *
     * @param targetUin
     */
    private void saveTargetUin(String targetUin) {
        if (targetUin != null) {
            SharedPreferences share = mActivity.getSharedPreferences(SHARE_PREF_NAME, 0);
            SharedPreferences.Editor editor = share.edit();
            editor.putString(KEY_TARGET_QQ_UIN, targetUin);
            editor.apply();
        }
    }


    /**
     * 回调
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public void onActivityResultData(int requestCode, int resultCode, Intent data) {
        Tencent.onActivityResultData(requestCode, resultCode, data, loginAuLoginListener);
    }

}
